import type { WatchStopHandle } from 'vue'

export interface VDelayRenderOptions {
  /**
   * 延迟时间
   */
  delay?: number
  /**
   * 渲染帧
   */
  frame?: number
}
/**
 * 延迟渲染
 * @param maxFrameIndex 动画帧最大数
 */
export function useDefineDelayRender(maxFrameIndex = 100) {
  /** 记录当前帧 */
  const [frameIndex, setFrameIndex] = useState(0)
  /** 记录动画帧 */
  let global = 0
  /**
   * 记录最大设置延迟数
   * 用于默认延迟帧累加
   */
  // let settingMaxFrameIndex = 0;
  let watchController: WatchStopHandle | null = null
  /** 记录帧回调函数 */
  let frameCallback: Function | null = null

  watchController = watch(
    () => frameIndex.value,
    handleFrameRender,
    {
      immediate: true,
    },
  )
  onBeforeUnmount(() => {
    destroy()
  })
  async function handleFrameRender(n: number) {
    const res = await frameCallback?.(n)
    if (typeof res === 'boolean' && res) {
      destroy()
    }
  }
  function updataFrameIndex() {
    global = requestAnimationFrame(() => {
      if (
        maxFrameIndex > 0
        && maxFrameIndex <= frameIndex.value
      ) {
        destroy()
        return
      }
      frameIndex.value++
      updataFrameIndex()
    })
  }
  function destroy() {
    cancelAnimationFrame?.(global)
    setFrameIndex?.(0)
    watchController?.()
  }
  function registerFrameCallback<
    T extends (n: number) => any,
  >(callback: T) {
    frameCallback = callback
  }
  return {
    registerFrameCallback,
    updataFrameIndex,
    destroy,
  }
}
